package com.baymax.study.tuLing.netty.d2_advanced;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * 粘包半包问题解决方式
 * 根据消息内容长度，在头部添加消息长度字段
 *
 * @author baymax
 * @since 2025-07-01
 */
public class Demo1_LengthField {
    static class Test1 {
        public static void main(String[] args) {
            EmbeddedChannel channel = new EmbeddedChannel(
                // 参数含义：1024-缓存区大小，0-从0开始计算长度，4-长度所占用的字节数（int 占4个字节），0-内容相比较长度字段的偏移量，4-要剥离的初始字节（0 表示不摸出）
                new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4),
                // 日志打印
                new LoggingHandler(LogLevel.INFO));

            ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
            send(buffer, "hello, world");
            send(buffer, "Hi!");
            channel.writeInbound(buffer);
        }

        private static void send(ByteBuf buffer, String content) {
            byte[] bytes = content.getBytes();
            buffer.writeInt(bytes.length); // 消息长度
            buffer.writeBytes(bytes); // 实际内容
        }
    }

    static class Test2 {
        public static void main(String[] args) {
            EmbeddedChannel channel = new EmbeddedChannel(
                // 参数含义：1024-缓存区大小，0-从0开始计算长度，4-长度所占用的字节数（int 占4个字节），【1】-内容相比较长度字段的偏移量，4-要剥离的初始字节（0 表示不摸出）
                new LengthFieldBasedFrameDecoder(1024, 0, 4, 1, 4),
                // 日志打印【输出结果中会保留版本号】
                new LoggingHandler(LogLevel.INFO));

            ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
            send(buffer, "hello, world");
            send(buffer, "Hi!");
            channel.writeInbound(buffer);
        }

        private static void send(ByteBuf buffer, String content) {
            byte[] bytes = content.getBytes();
            buffer.writeInt(bytes.length); // 消息长度
            buffer.writeByte(1); // 【添加一个版本号】
            buffer.writeBytes(bytes); // 实际内容
        }
    }
}
